<template>
  <div class="task-process-designer" @click="handlePageClick">
    <TopNavigation :showOrganizationSection="false" :showTaskRoleSection="false" />
    
    <!-- 初始界面：流程定义管理 -->
    <div v-if="viewMode === 'list'" class="initial-view">
      <div class="page-header">
        <h2>流程定义管理</h2>
        <div class="toolbar-actions">
          <button class="btn btn-primary" @click="startNewProcess"><span>新建流程</span></button>
        </div>
      </div>
      
      <!-- 流程配置列表 -->
      <div class="process-list-card">
        <div v-if="loading" class="loading-state">
          <div class="loading-icon">⏳</div>
          <div class="loading-text">加载中...</div>
        </div>
        
        <div v-else-if="processConfigs.length === 0" class="empty-state">
          <div class="empty-icon">📋</div>
          <div class="empty-text">暂无流程定义</div>
          <div class="empty-subtext">点击"新建流程"开始创建您的第一个流程</div>
        </div>
        
        <div v-else class="process-list">
          <div class="process-item-header">
            <div class="process-name-column">流程名称</div>
            <div class="process-description-column">描述</div>
            <div class="process-actions-column">操作</div>
          </div>
          
          <div v-for="process in processConfigs" :key="process.id" class="process-item">
            <div class="process-name-column">{{ process.name }}</div>
            <div class="process-description-column">{{ process.description || '-' }}</div>
            <div class="process-actions-column">
              <button class="btn btn-secondary btn-sm" @click="editProcess(process)"><span>编辑</span></button>
              <button class="btn btn-danger btn-sm" @click="deleteProcess(process.id)"><span>删除</span></button>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 主界面：流程设计器 -->
    <div v-else>
    
    <div class="page-header">
        <h2>任务流程定义</h2>
        <div class="toolbar-actions">
          <button class="btn btn-secondary" @click="returnToListView"><span>返回</span></button>
          <button class="btn btn-secondary"><span>保存草稿</span></button>
          <button class="btn btn-primary"><span>发布流程</span></button>
        </div>
      </div>
    
    <!-- 第一部分：流程基本信息（在上方） -->
    <div class="process-info-card">
      <h3 class="section-title">流程基本信息</h3>
      <div class="form-container">
        <div class="form-row">
          <div class="form-item">
            <label class="form-label">流程名称</label>
            <input 
              type="text" 
              class="input form-control" 
              v-model="name" 
              placeholder="请输入流程名称"
            >
          </div>
          <div class="form-item">
            <label class="form-label">流程描述</label>
            <input 
              type="text" 
              class="input form-control"
              v-model="description"
              placeholder="请输入流程描述"
            >
          </div>
        </div>
        <div class="form-row">
          <div class="form-item">
            <label class="form-label">是否启用</label>
            <input 
              type="text" 
              class="input form-control"
              v-model="enabled" 
              placeholder="请输入0或1"
            >
          </div>
          <div class="form-item">
            <label class="form-label">版本号</label>
            <input 
              type="text" 
              class="input form-control"
              v-model="version" 
              placeholder="请输入版本号"
            >
          </div>
          <div class="form-item" style="display: flex; align-items: flex-end;">
            <button class="btn btn-primary" @click="createNewProcess"><span>新建</span></button>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 下方布局：流程节点栏在左侧，节点配置在右侧 -->
    <div class="designer-bottom-layout">
      <!-- 第二部分：流程节点（在下方左侧） -->
      <div class="designer-section nodes-section card">
        <div class="toolbar">
            <h3>流程节点</h3>
            <button class="btn btn-primary" @click="addNode"><span>+ 添加节点</span></button>
          </div>
        
        <div class="nodes-container">
          <!-- 开始节点 -->
          <div class="node-item start-node" :class="{ 'selected': selectedNode?.id === 'start' }" @click="selectNode('start')">
            <div class="node-icon">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <circle cx="12" cy="12" r="10"></circle>
                <polyline points="12 8 12 12 16 12"></polyline>
              </svg>
            </div>
            <div class="node-content">
              <div class="node-title">开始</div>
            </div>
          </div>
          
          <!-- 动态节点 -->
          <div v-for="node in processNodes" :key="node.id" class="node-item" :class="{ 'selected': selectedNode?.id === node.id }" @click="selectNode(node)">
            <div class="node-icon">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect>
                <line x1="3" y1="9" x2="21" y2="9"></line>
                <line x1="9" y1="21" x2="9" y2="9"></line>
              </svg>
            </div>
            <div class="node-content">
              <div class="node-title">{{ node.nodeName || '节点名nodeName' }}</div>
              <div class="node-type">{{ getNodeTypeName(node) }}</div>
            </div>
            <button class="node-delete-btn" @click.stop="deleteNode(node.id)">
              <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <line x1="18" y1="6" x2="6" y2="18"></line>
                <line x1="6" y1="6" x2="18" y2="18"></line>
              </svg>
            </button>
          </div>
          
          <!-- 结束节点 -->
          <div class="node-item end-node" :class="{ 'selected': selectedNode?.id === 'end' }" @click="selectNode('end')">
            <div class="node-icon">
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                <circle cx="12" cy="12" r="10"></circle>
                <polyline points="8 12 12 12 12 16"></polyline>
              </svg>
            </div>
            <div class="node-content">
              <div class="node-title">结束</div>
            </div>
          </div>
          
          <!-- 连接线 - 这里简化处理，实际可能需要更复杂的连线逻辑 -->
          <div class="connections">
            <div v-for="(node, index) in processNodesWithConnections" :key="`connection-${index}`" class="connection-line"></div>
          </div>
        </div>
      </div>
      
      <!-- 第三部分：节点配置（在下方右侧） -->
      <div class="designer-section configuration-section card">
        <div class="toolbar">
          <h3>节点配置</h3>
        </div>
        
        <div v-if="!selectedNode" class="no-selection">
          <div class="no-selection-content">
            <svg class="no-selection-icon" width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round">
              <circle cx="12" cy="12" r="10"></circle>
              <line x1="12" y1="8" x2="12" y2="16"></line>
              <line x1="8" y1="12" x2="16" y2="12"></line>
            </svg>
            <p>请选择一个节点进行配置</p>
          </div>
        </div>
        
        <div v-else class="node-configuration">
          <!-- 开始节点配置 -->
          <div v-if="selectedNode.id === 'start'" class="start-node-config">
            <div class="config-section">
              <h4>开始节点设置</h4>
              <div class="form-item">
                <label class="form-label">节点名称</label>
                <input type="text" class="input form-control" value="开始" readonly>
              </div>
            </div>
          </div>
          
          <!-- 结束节点配置 -->
          <div v-else-if="selectedNode.id === 'end'" class="end-node-config">
            <div class="config-section">
              <h4>结束节点设置</h4>
              <div class="form-item">
                <label class="form-label">节点名称</label>
                <input type="text" class="input form-control" value="结束" readonly>
              </div>
            </div>
          </div>
          
          <!-- 普通节点配置 -->
          <div v-else class="normal-node-config">
            <div class="config-section">
              <h4>基本配置</h4>
              <div class="form-item">
                <label class="form-label">节点名称</label>
                <input type="text" class="input form-control" v-model="selectedNode.nodeName" placeholder="请输入节点名称" @blur="updateNodeInfo">
              </div>
              <div class="form-item">
                <label class="form-label">处理角色</label>
                <select class="select form-control" v-model="selectedNode.role" @change="updateNodeInfo">
                  <option value="">请选择处理角色</option>
                  <!-- 如果当前节点的role存在且不在角色列表中，显示当前值作为不可编辑选项 -->
                  <option v-if="selectedNode.role && !roleList.some(r => r.name === selectedNode.role)" :value="selectedNode.role" disabled>
                    {{ selectedNode.role }}
                  </option>
                  <!-- 正常的角色列表选项 -->
                  <option v-for="role in roleList" :key="role.id" :value="role.name">{{ role.name }}</option>
                </select>
              </div>
            </div>
            
            <div class="config-section">
              <div style="display: flex; align-items: center; gap: 10px;">
                <h4>反馈表单设计</h4>
                <textarea 
                  class="form-control json-preview-small" 
                  :value="selectedNode && selectedNode.nodeContent ? formatNodeContent(selectedNode.nodeContent) : ''" 
                  readonly 
                  placeholder="表单JSON数据"
                  rows="3"
                  style="font-family: monospace; font-size: 12px; flex: 1; min-width: 0;"
                ></textarea>
                <button class="btn btn-secondary" @click="copyJsonToClipboard"><span>复制</span></button>
              </div>
              <div style="display: flex; justify-content: center; align-items: center; height: 200px; border: 1px dashed #dcdfe6; border-radius: 8px;">
                <img src="" alt="表单设计" style="max-width: 80px; max-height: 80px; margin-bottom: 10px;">
                <div style="text-align: center;">
                  <p style="margin: 0 0 10px 0;">设计反馈表单</p>
                  <button class="btn btn-primary" @click="openFormDesigner(selectedNode.id)"><span>打开表单设计器</span></button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
  </div>
  
  <!-- 添加节点模态框 -->
  <div v-if="showAddNodeModal" class="modal" @click="closeAddNodeModal">
    <div class="modal-content" @click.stop>
      <div class="modal-header">
        <h3>添加节点</h3>
        <button class="modal-close" @click="closeAddNodeModal">×</button>
      </div>
      <div class="modal-body">
        <div class="form-container">
          <div class="form-item">
            <label class="form-label">顺序栏 <span class="required">*</span></label>
            <input type="number" class="input form-control" v-model="newNodeForm.nodeOrder" placeholder="请输入节点顺序">
            <div v-if="errors.nodeOrder" class="error-message">{{ errors.nodeOrder }}</div>
          </div>
          <div class="form-item">
            <label class="form-label">节点名 <span class="required">*</span></label>
            <input type="text" class="input form-control" v-model="newNodeForm.nodeName" placeholder="请输入节点名">
            <div v-if="errors.nodeName" class="error-message">{{ errors.nodeName }}</div>
          </div>
          <div class="form-item">
              <label class="form-label">部门 <span class="required">*</span></label>
              <select class="select form-control" v-model="newNodeForm.department">
                <option value="">请选择部门</option>
                <option v-for="dept in departmentList" :key="dept.deptId" :value="dept.deptName">{{ dept.deptName }}</option>
              </select>
              <div v-if="errors.department" class="error-message">{{ errors.department }}</div>
            </div>
            <div class="form-item">
              <label class="form-label">角色 <span class="required">*</span></label>
              <select class="select form-control" v-model="newNodeForm.role">
                <option value="">请选择角色</option>
                <option v-for="role in roleList" :key="role.id" :value="role.roleName">{{ role.roleName }}</option>
              </select>
              <div v-if="errors.role" class="error-message">{{ errors.role }}</div>
            </div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-secondary" @click="closeAddNodeModal"><span>取消</span></button>
        <button class="btn btn-primary" @click="submitAddNodeForm"><span>确定</span></button>
      </div>
    </div>
  </div>

  <!-- 表单设计器模态框 -->
  <div v-if="showFormDesigner" class="modal" @click="closeFormDesigner">
    <div class="modal-content designer-modal" @click.stop>
      <div class="modal-header">
        <h3>表单设计器</h3>
        <button class="modal-close" @click="closeFormDesigner">×</button>
      </div>
      <div class="modal-body">
        <div class="designer-header">
          <div class="title-container">
            <h2 class="page-title">反馈表单设计</h2>
            <div class="breadcrumb">任务流程 > 节点配置 > 表单设计</div>
          </div>
          <div class="action-buttons">
            <button class="btn btn-secondary" @click="previewForm"><span>预览</span></button>
        <button class="btn btn-secondary" @click="showJson"><span>查看JSON</span></button>
        <button class="btn btn-primary" @click="saveForm"><span>保存</span></button>
          </div>
        </div>

        <div class="designer-content">
          <!-- 左侧组件库 -->
          <div class="components-panel">
            <h3 class="panel-title">组件库</h3>
            
            <!-- 基础组件 -->
            <div class="component-category">
              <div class="category-header" @click="toggleCategory('basic')">
                <span class="category-name">基础组件</span>
                <svg class="icon" :class="{ 'rotate': expandedCategories.basic }" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6 9 12 15 18 9"></polyline>
                </svg>
              </div>
              <div v-if="expandedCategories.basic" class="category-content">
                <div v-for="component in basicComponents" :key="component.id" class="component-item" draggable="true" @dragstart="onDragStart(component)">
                  <span class="component-icon">{{ component.icon }}</span>
                  <span class="component-name">{{ component.name }}</span>
                </div>
              </div>
            </div>
            
            <!-- 选择组件 -->
            <div class="component-category">
              <div class="category-header" @click="toggleCategory('select')">
                <span class="category-name">选择组件</span>
                <svg class="icon" :class="{ 'rotate': expandedCategories.select }" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6 9 12 15 18 9"></polyline>
                </svg>
              </div>
              <div v-if="expandedCategories.select" class="category-content">
                <div v-for="component in selectComponents" :key="component.id" class="component-item" draggable="true" @dragstart="onDragStart(component)">
                  <span class="component-icon">{{ component.icon }}</span>
                  <span class="component-name">{{ component.name }}</span>
                </div>
              </div>
            </div>
            
            <!-- 日期时间组件 -->
            <div class="component-category">
              <div class="category-header" @click="toggleCategory('date')">
                <span class="category-name">日期时间</span>
                <svg class="icon" :class="{ 'rotate': expandedCategories.date }" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6 9 12 15 18 9"></polyline>
                </svg>
              </div>
              <div v-if="expandedCategories.date" class="category-content">
                <div v-for="component in dateComponents" :key="component.id" class="component-item" draggable="true" @dragstart="onDragStart(component)">
                  <span class="component-icon">{{ component.icon }}</span>
                  <span class="component-name">{{ component.name }}</span>
                </div>
              </div>
            </div>
            
            <!-- 高级组件 -->
            <div class="component-category">
              <div class="category-header" @click="toggleCategory('advanced')">
                <span class="category-name">高级组件</span>
                <svg class="icon" :class="{ 'rotate': expandedCategories.advanced }" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                  <polyline points="6 9 12 15 18 9"></polyline>
                </svg>
              </div>
              <div v-if="expandedCategories.advanced" class="category-content">
                <div v-for="component in advancedComponents" :key="component.id" class="component-item" draggable="true" @dragstart="onDragStart(component)">
                  <span class="component-icon">{{ component.icon }}</span>
                  <span class="component-name">{{ component.name }}</span>
                </div>
              </div>
            </div>
          </div>
          
          <!-- 中间设计区域 -->
          <div class="design-area">
            <div class="form-container" @dragover="onDragOver" @drop="onDrop">
              <template v-if="formComponents.length > 0">
                <div v-for="(component, index) in formComponents" :key="component.id" class="form-component" :class="{ 'selected': selectedComponentId === component.id }" @click="selectComponent(component.id)">
                  <div class="component-content">
                    <div class="component-label">{{ component.label || component.name }}</div>
                    <div class="component-preview">
                      <div v-if="component.type === 'input'">
                        <input type="text" :placeholder="component.placeholder || '请输入...'" v-model="component.placeholder" readonly class="preview-input">
                      </div>
                      <div v-else-if="component.type === 'textarea'">
                        <textarea :placeholder="component.placeholder || '请输入...'" v-model="component.placeholder" readonly class="preview-textarea"></textarea>
                      </div>
                      <div v-else-if="component.type === 'checkbox'">
                        <div class="checkbox-group">
                          <label v-for="option in component.options" :key="option.value">
                            <input type="checkbox" disabled>
                            <span>{{ option.label }}</span>
                          </label>
                        </div>
                      </div>
                      <div v-else-if="component.type === 'radio'">
                        <div class="radio-group">
                          <label v-for="option in component.options" :key="option.value">
                            <input type="radio" name="radio-preview-{{component.id}}" disabled>
                            <span>{{ option.label }}</span>
                          </label>
                        </div>
                      </div>
                      <div v-else-if="component.type === 'select'">
                        <select disabled class="preview-select">
                          <option value="">{{ component.placeholder || '请选择...' }}</option>
                          <option v-for="option in component.options" :key="option.value" :value="option.value">{{ option.label }}</option>
                        </select>
                      </div>
                      <div v-else-if="component.type === 'date'">
                        <input type="date" :placeholder="component.placeholder || '选择日期'" :value="component.dateValue" readonly class="preview-date">
                      </div>
                      <div v-else-if="component.type === 'datetime'">
                        <input type="datetime-local" :placeholder="component.placeholder || '选择日期时间'" :value="component.dateTimeValue" readonly class="preview-datetime">
                      </div>
                      <div v-else-if="component.type === 'array'">
                        <div class="array-container" @dragover="onArrayDragOver($event, component.id)" @drop="onArrayDrop($event, component.id)">
                          <div class="array-header">
                            <span>{{ component.label || '数据容器' }}</span>
                            <span class="array-count">({{ component.items?.length || 0 }}个子组件)</span>
                          </div>
                          <div class="array-items">
                            <div v-if="component.items && component.items.length > 0">
                              <div v-for="item in component.items" :key="item.id" class="array-item">
                                <div class="array-item-label">子组件: {{ item.label }}</div>
                                <div v-if="item.type === 'input'">
                                  <input type="text" :placeholder="item.placeholder || '请输入...'" readonly class="preview-input">
                                </div>
                                <div v-else-if="item.type === 'textarea'">
                                  <textarea :placeholder="item.placeholder || '请输入...'" readonly class="preview-textarea"></textarea>
                                </div>
                                <div v-else-if="item.type === 'checkbox'">
                                  <div class="checkbox-group">
                                    <label v-for="option in item.options" :key="option.value">
                                      <input type="checkbox" disabled>
                                      <span>{{ option.label }}</span>
                                    </label>
                                  </div>
                                </div>
                                <div v-else-if="item.type === 'radio'">
                                  <div class="radio-group">
                                    <label v-for="option in item.options" :key="option.value">
                                      <input type="radio" name="radio-preview-{{item.id}}" disabled>
                                      <span>{{ option.label }}</span>
                                    </label>
                                  </div>
                                </div>
                                <div v-else-if="item.type === 'select'">
                                  <select disabled class="preview-select">
                                    <option value="">{{ item.placeholder || '请选择...' }}</option>
                                    <option v-for="option in item.options" :key="option.value" :value="option.value">{{ option.label }}</option>
                                  </select>
                                </div>
                                <div v-else-if="item.type === 'date'">
                                  <input type="date" :placeholder="item.placeholder || '选择日期'" :value="item.dateValue" readonly class="preview-date">
                                </div>
                                <div v-else-if="item.type === 'datetime'">
                                  <input type="datetime-local" :placeholder="item.placeholder || '选择日期时间'" :value="item.dateTimeValue" readonly class="preview-datetime">
                                </div>
                                <div v-else-if="item.type === 'divider'">
                                  <div class="divider"></div>
                                  <div v-if="item.label" class="divider-label">{{ item.label }}</div>
                                </div>
                                <div v-else>
                                  {{ item.name }}
                                </div>
                              </div>
                            </div>
                            <div v-else class="empty-array">
                              拖拽组件到此处添加子组件
                            </div>
                          </div>
                        </div>
                      </div>
                      <div v-else-if="component.type === 'divider'">
                        <div class="divider"></div>
                        <div v-if="component.label" class="divider-label">{{ component.label }}</div>
                      </div>
                      <div v-else>
                        {{ component.name }}
                      </div>
                    </div>
                  </div>
                  
                  <!-- 组件操作按钮 -->
                  <div class="component-actions">
                    <button class="action-btn move-up-btn" title="上移" @click.stop="moveComponentUp(index)" :disabled="index === 0">
                      <svg class="icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <polyline points="18 15 12 9 6 15"></polyline>
                      </svg>
                    </button>
                    <button class="action-btn move-down-btn" title="下移" @click.stop="moveComponentDown(index)" :disabled="index === formComponents.length - 1">
                      <svg class="icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <polyline points="6 9 12 15 18 9"></polyline>
                      </svg>
                    </button>
                    <button class="action-btn copy-btn" title="复制" @click.stop="copyComponent(index)">
                      <svg class="icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect>
                        <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path>
                      </svg>
                    </button>
                    <button class="action-btn delete-btn" title="删除" @click.stop="deleteComponent(index)">
                      <svg class="icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
                        <polyline points="3 6 5 6 21 6"></polyline>
                        <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
                        <line x1="10" y1="11" x2="10" y2="17"></line>
                        <line x1="14" y1="11" x2="14" y2="17"></line>
                      </svg>
                    </button>
                  </div>
                </div>
              </template>
              <div v-else class="empty-form">
                <div class="empty-icon">📝</div>
                <div class="empty-text">从左侧组件库拖拽组件到此处开始设计表单</div>
              </div>
            </div>
          </div>
          
          <!-- 右侧属性配置面板 -->
          <div class="properties-panel">
            <h3 class="panel-title">属性配置</h3>
            <div v-if="selectedComponent">
              <div class="property-section">
                <h4 class="section-title">字段属性</h4>
                <div class="property-item">
                  <label class="property-label">标签名称</label>
                  <input type="text" v-model="selectedComponent.label" class="property-input">
                </div>
                <div class="property-item">
                  <label class="property-label">字段名称</label>
                  <input type="text" v-model="selectedComponent.name" class="property-input">
                </div>
                <template v-if="!['date', 'datetime'].includes(selectedComponent.type)">
                  <div class="property-item">
                    <label class="property-label">占位符</label>
                    <input type="text" v-model="selectedComponent.placeholder" class="property-input">
                  </div>
                </template>
                <template v-if="selectedComponent.type !== 'divider'">
                  <div class="property-item">
                    <label class="property-label">默认值</label>
                    <input type="text" v-model="selectedComponent.defaultValue" class="property-input">
                  </div>
                </template>
              </div>

              <!-- 根据组件类型显示不同的属性 -->
              <div v-if="selectedComponent.type === 'array'" class="property-section">
                <h4 class="section-title">子组件配置</h4>
                <div class="array-children">
                  <div v-if="selectedComponent.items && selectedComponent.items.length > 0">
                    <div v-for="(item, idx) in selectedComponent.items" :key="item.id" class="array-child-item">
                      <div class="array-child-header">
                        <button class="edit-child-btn" @click.stop="editArrayChild(idx)" title="编辑子组件">
                          ✏️
                        </button>
                        <span>{{ item.label || item.name }}</span>
                        <button class="remove-child-btn" @click.stop="removeArrayChild(idx)">×</button>
                      </div>
                      <div v-if="editingChildIndex === idx" class="array-child-properties">
                        <h4 class="section-title">字段属性</h4>
                        <div class="property-item">
                          <label class="property-label">标签名</label>
                          <input type="text" v-model="selectedComponent.items[idx].label" class="property-input small-input">
                        </div>
                        <div class="property-item">
                          <label class="property-label">字段名</label>
                          <input type="text" v-model="selectedComponent.items[idx].name" class="property-input small-input">
                        </div>
                        <template v-if="!['date', 'datetime'].includes(selectedComponent.items[idx].type)">
                          <div class="property-item">
                            <label class="property-label">占位符</label>
                            <input type="text" v-model="selectedComponent.items[idx].placeholder" class="property-input small-input">
                          </div>
                        </template>
                        <template v-if="selectedComponent.items[idx].type !== 'divider'">
                          <div class="property-item">
                            <label class="property-label">默认值</label>
                            <input type="text" v-model="selectedComponent.items[idx].defaultValue" class="property-input small-input">
                          </div>
                        </template>

                        <!-- 根据子组件类型显示不同的属性 -->
                        <div v-if="['select', 'checkbox', 'radio'].includes(selectedComponent.items[idx].type)" class="property-section">
                          <h4 class="section-title">选项配置</h4>
                          <div v-if="selectedComponent.items[idx].options && selectedComponent.items[idx].options.length > 0">
                            <div v-for="(option, optIdx) in selectedComponent.items[idx].options" :key="option.value" class="option-item">
                              <input type="text" v-model="option.label" placeholder="选项文本" class="option-input small-input">
                              <input type="text" v-model="option.value" placeholder="选项值" class="option-input small-input">
                              <button class="remove-option-btn" @click.stop="removeChildOption(idx, optIdx)">×</button>
                            </div>
                          </div>
                          <button class="add-option-btn small-btn" @click.stop="addChildOption(idx)">添加选项</button>
                        </div>
                        
                        
                        <div v-if="selectedComponent.items[idx].type === 'date'" class="property-section">
                          <h4 class="section-title">日期配置</h4>
                          <div class="property-item">
                            <label class="property-label">默认日期</label>
                            <input type="date" v-model="selectedComponent.items[idx].dateValue" class="property-input small-input">
                          </div>
                        </div>
                        
                        <div v-if="selectedComponent.items[idx].type === 'datetime'" class="property-section">
                          <h4 class="section-title">日期时间配置</h4>
                          <div class="property-item">
                            <label class="property-label">默认日期时间</label>
                            <input type="datetime-local" v-model="selectedComponent.items[idx].dateTimeValue" class="property-input small-input">
                          </div>
                        </div>

                        <div class="property-section">
                          <h4 class="section-title">样式设置</h4>
                          <div class="property-item">
                            <label class="property-label">宽度</label>
                            <input type="text" v-model="selectedComponent.items[idx].width" class="property-input small-input">
                          </div>
                        </div>

                        <div class="property-section">
                          <h4 class="section-title">验证规则</h4>
                          <div class="property-item checkbox-item">
                            <label class="checkbox-label">
                              <input type="checkbox" v-model="selectedComponent.items[idx].required">
                              必填项
                            </label>
                          </div>
                        </div>

                        <button class="save-child-btn" @click.stop="editingChildIndex = null">保存</button>
                      </div>
                    </div>
                  </div>
                  <button class="add-child-btn" @click.stop="addArrayChild">添加子组件</button>
                </div>
              </div>

              <div v-if="['select', 'checkbox', 'radio'].includes(selectedComponent.type)" class="property-section">
                <h4 class="section-title">选项配置</h4>
                <div v-if="selectedComponent.options && selectedComponent.options.length > 0">
                  <div v-for="(option, idx) in selectedComponent.options" :key="option.value" class="option-item">
                    <input type="text" v-model="option.label" placeholder="选项文本" class="option-input">
                    <input type="text" v-model="option.value" placeholder="选项值" class="option-input">
                    <button class="remove-option-btn" @click.stop="removeOption(idx)">×</button>
                  </div>
                </div>
                <button class="add-option-btn" @click.stop="addOption">添加选项</button>
              </div>
              
              <!-- 日期和时间组件配置 -->
              <div v-if="selectedComponent.type === 'date'" class="property-section">
                <h4 class="section-title">日期配置</h4>
                <div class="property-item">
                  <label class="property-label">日期时间</label>
                  <input type="date" v-model="selectedComponent.dateValue" class="property-input">
                </div>
              </div>
              
              <div v-if="selectedComponent.type === 'datetime'" class="property-section">
                <h4 class="section-title">日期时间配置</h4>
                <div class="property-item">
                  <label class="property-label">日期时间</label>
                  <input type="datetime-local" v-model="selectedComponent.dateTimeValue" class="property-input">
                </div>
              </div>

              <div class="property-section">
                <h4 class="section-title">样式设置</h4>
                <div class="property-item">
                  <label class="property-label">宽度</label>
                  <input type="text" v-model="selectedComponent.width" class="property-input">
                </div>
              </div>

              <div class="property-section">
                <h4 class="section-title">验证规则</h4>
                <div class="property-item checkbox-item">
                  <label class="checkbox-label">
                    <input type="checkbox" v-model="selectedComponent.required">
                    必填项
                  </label>
                </div>
              </div>
            </div>
            <div v-else class="no-selection">
              <p>请选择一个组件进行编辑</p>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>

  <!-- 预览模态框 -->
  <div v-if="showPreview" class="modal" @click="closePreview">
    <div class="modal-content" @click.stop>
      <div class="modal-header">
        <h3>表单预览</h3>
        <button class="modal-close" @click="closePreview">×</button>
      </div>
      <div class="modal-body">
        <div class="preview-form">
          <div v-for="component in formComponents" :key="component.id" class="preview-form-component">
            <div class="component-label">{{ component.label || component.name }}</div>
            <div class="component-preview">
              <div v-if="component.type === 'input'">
                <input type="text" :placeholder="component.placeholder || '请输入...'" class="preview-input">
              </div>
              <div v-else-if="component.type === 'textarea'">
                <textarea :placeholder="component.placeholder || '请输入...'" class="preview-textarea"></textarea>
              </div>
              <div v-else-if="component.type === 'checkbox'">
                <div class="checkbox-group">
                  <label v-for="option in component.options" :key="option.value">
                    <input type="checkbox">
                    <span>{{ option.label }}</span>
                  </label>
                </div>
              </div>
              <div v-else-if="component.type === 'radio'">
                <div class="radio-group">
                  <label v-for="option in component.options" :key="option.value">
                    <input type="radio" name="radio-preview-{{component.id}}">
                    <span>{{ option.label }}</span>
                  </label>
                </div>
              </div>
              <div v-else-if="component.type === 'select'">
                <select class="preview-select">
                  <option value="">{{ component.placeholder || '请选择...' }}</option>
                  <option v-for="option in component.options" :key="option.value" :value="option.value">{{ option.label }}</option>
                </select>
              </div>
              <div v-else-if="component.type === 'date'">
                <input type="date" :placeholder="component.placeholder || '选择日期'" :value="component.dateValue" class="preview-date">
              </div>
              <div v-else-if="component.type === 'datetime'">
                <input type="datetime-local" :placeholder="component.placeholder || '选择日期时间'" :value="component.dateTimeValue" class="preview-datetime">
              </div>
              <div v-else-if="component.type === 'array'">
                <div class="array-container">
                  <div class="array-header">
                    <span>{{ component.label || '数据容器' }}</span>
                    <span class="array-count">({{ component.items?.length || 0 }}个子组件)</span>
                  </div>
                  <div class="array-items">
                    <div v-if="component.items && component.items.length > 0">
                      <div v-for="item in component.items" :key="item.id" class="array-item">
                        <div class="array-item-label">子组件: {{ item.label }}</div>
                        <div v-if="item.type === 'input'">
                          <input type="text" :placeholder="item.placeholder || '请输入...'" class="preview-input">
                        </div>
                        <div v-else-if="item.type === 'textarea'">
                          <textarea :placeholder="item.placeholder || '请输入...'" class="preview-textarea"></textarea>
                        </div>
                        <div v-else-if="item.type === 'checkbox'">
                          <div class="checkbox-group">
                            <label v-for="option in item.options" :key="option.value">
                              <input type="checkbox">
                              <span>{{ option.label }}</span>
                            </label>
                          </div>
                        </div>
                        <div v-else-if="item.type === 'radio'">
                          <div class="radio-group">
                            <label v-for="option in item.options" :key="option.value">
                              <input type="radio" name="radio-preview-{{item.id}}">
                              <span>{{ option.label }}</span>
                            </label>
                          </div>
                        </div>
                        <div v-else-if="item.type === 'select'">
                          <select class="preview-select">
                            <option value="">{{ item.placeholder || '请选择...' }}</option>
                            <option v-for="option in item.options" :key="option.value" :value="option.value">{{ option.label }}</option>
                          </select>
                        </div>
                        <div v-else-if="item.type === 'date'">
                          <input type="date" :placeholder="item.placeholder || '选择日期'" :value="item.dateValue" class="preview-date">
                        </div>
                        <div v-else-if="item.type === 'datetime'">
                          <input type="datetime-local" :placeholder="item.placeholder || '选择日期时间'" :value="item.dateTimeValue" class="preview-datetime">
                        </div>
                        <div v-else-if="item.type === 'divider'">
                          <div class="divider"></div>
                          <div v-if="item.label" class="divider-label">{{ item.label }}</div>
                        </div>
                        <div v-else>
                          {{ item.name }}
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
              <div v-else-if="component.type === 'divider'">
                <div class="divider"></div>
                <div v-if="component.label" class="divider-label">{{ component.label }}</div>
              </div>
              <div v-else>
                {{ component.name }}
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="modal-footer">
        <button class="btn btn-primary" @click="handlePreviewSubmit"><span>提交</span></button>
        <button class="btn btn-default" @click="closePreview"><span>关闭</span></button>
      </div>
    </div>
  </div>

  <!-- JSON查看模态框 -->
  <div v-if="showJsonModal" class="modal" @click="closeJsonModal">
    <div class="modal-content json-modal" @click.stop>
      <div class="modal-header">
        <h3>表单JSON</h3>
        <button class="modal-close" @click="closeJsonModal">×</button>
      </div>
      <div class="modal-body">
        <pre class="json-preview">{{ formattedJson }}</pre>
      </div>
      <div class="modal-footer">
        <button class="btn btn-default" @click="copyJson"><span>复制</span></button>
        <button class="btn btn-primary" @click="closeJsonModal"><span>关闭</span></button>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import TopNavigation from '../components/TopNavigation.vue'
import { getProcessConfigs, deleteProcessConfig, getProcessConfigDetail, createProcessConfig, updateProcessConfig } from '../services/processConfigService.js'
import { getRoleConfigs } from '../services/roleConfigService.js'
import { deleteProcessNode, createProcessNode, updateProcessNode } from '../services/processNodeService.js'
import departmentService from '../services/departmentService.js'

const router = useRouter()

// 流程基本信息
const name = ref('')

const description = ref('')

const enabled = ref(1) // 1表示启用，0表示禁用

const version = ref(1)

// 流程配置列表
const processConfigs = ref([])

// 加载中状态
const loading = ref(false)

// 流程节点列表
const processNodes = ref([])

// 选中的节点
const selectedNode = ref(null)

// 角色列表
const roleList = ref([])

// 部门列表
const departmentList = ref([])

// 视图模式控制：'list'表示初始列表界面，'design'表示流程设计界面
const viewMode = ref('list')

// 当前编辑的流程ID
const currentProcessId = ref(null)

// 上次自动保存时间
const lastAutoSaveTime = ref(0)

// 自动保存的时间间隔（毫秒）
const AUTO_SAVE_INTERVAL = 5000

// 新建流程
const createNewProcess = async () => {
  if (!name.value.trim()) {
    alert('请输入流程名称')
    return
  }
  
  try {
    loading.value = true
    // 处理status值，已经是数值类型
    let statusValue = enabled.value; // 1表示启用，0表示禁用
    
    const processData = {
      name: name.value,
      description: description.value,
      status: statusValue,
      version: parseInt(version.value) // 确保是整数类型
    }
    
    const response = await createProcessConfig(processData)
    alert('流程创建成功')
    
    // 重置表单
    name.value = ''
    description.value = ''
    enabled.value = 1
    version.value = 1
    processNodes.value = []
    selectedNode.value = null
  } catch (error) {
    console.error('创建流程失败:', error)
    alert('创建流程失败，请重试')
  } finally {
    loading.value = false
  }
}

// 切换到新建流程界面
const startNewProcess = () => {
  // 重置流程相关数据
  name.value = ''
  description.value = ''
  processNodes.value = []
  clearSelection()
  viewMode.value = 'design'
}

// 编辑流程配置
const editProcess = async (process) => {
  // 清除之前的选中状态
  clearSelection()
  
  // 根据流程ID加载流程详情
  try {
    loading.value = true
    const response = await getProcessConfigDetail(process.id)
    
    // 更新流程基本信息
    name.value = response.data.name || ''
    description.value = response.data.description || ''
    
    // 更新流程节点信息
    processNodes.value = response.data.nodes || []
    
    // 设置当前编辑的流程ID
    currentProcessId.value = process.id
    
    // 切换到设计视图
    viewMode.value = 'design'
  } catch (error) {
    console.error('获取流程详情失败:', error)
    // 可以添加错误提示
  } finally {
    loading.value = false
  }
}

// 自动保存流程配置
  const autoSaveProcessConfig = async () => {
    // 只有在编辑模式且有当前流程ID时才自动保存
    if (viewMode.value === 'design' && currentProcessId.value) {
      const now = Date.now()
      
      // 限制自动保存的频率，避免过于频繁的请求
      if (now - lastAutoSaveTime.value < AUTO_SAVE_INTERVAL) {
        return
      }
      
      try {
        const processData = {
          name: name.value,
          description: description.value,
          status: enabled.value, // 1表示启用，0表示禁用
          version: parseInt(version.value) // 确保是整数类型
        }
        
        await updateProcessConfig(currentProcessId.value, processData)
        console.log('流程配置自动保存成功')
        lastAutoSaveTime.value = now
        
        // 这里可以添加一个短暂的成功提示
      } catch (error) {
        console.error('自动保存流程配置失败:', error)
      }
    }
  }

// 点击页面时触发自动保存
const handlePageClick = (e) => {
  // 过滤掉特定元素的点击，避免过度保存
  if (e.target.tagName !== 'INPUT' && 
      e.target.tagName !== 'SELECT' && 
      e.target.tagName !== 'TEXTAREA' && 
      !e.target.closest('button')) {
    autoSaveProcessConfig()
  }
  
  // 移除了清除选中节点的代码，以便保持节点配置信息显示
}

// 删除流程配置
const deleteProcess = async (id) => {
  if (confirm('确定要删除这个流程配置吗？')) {
    try {
      await deleteProcessConfig(id)
      // 删除成功后更新本地列表
      processConfigs.value = processConfigs.value.filter(process => process.id !== id)
      // 可以添加成功提示
    } catch (error) {
      console.error('删除流程配置失败:', error)
      // 可以添加错误提示
    }
  }
}

// 返回流程定义管理界面
const returnToListView = () => {
  viewMode.value = 'list'
  selectedNode.value = null
}

// 切换视图或流程时清除选中的节点
const clearSelection = () => {
  selectedNode.value = null
}

// 获取流程配置列表
const loadProcessConfigs = async () => {
  loading.value = true
  try {
    const response = await getProcessConfigs()
    processConfigs.value = response.data || []
  } catch (error) {
    console.error('获取流程配置列表失败:', error)
  } finally {
    loading.value = false
  }
}

// 加载角色列表
const loadRoles = async () => {
  try {
    const response = await getRoleConfigs()
    roleList.value = response.data || []
  } catch (error) {
    console.error('获取角色列表失败:', error)
  }
}

// 加载部门列表
const loadDepartments = async () => {
  try {
    console.log('正在调用API获取部门数据...')
    const response = await departmentService.getDepartments()
    console.log('部门数据API响应:', response)
    if (response && response.code === 200) {
      departmentList.value = response.data || []
      console.log('成功获取部门数据，共', departmentList.value.length, '条')
    } else {
      departmentList.value = []
      console.error('获取部门数据失败，响应格式不正确')
    }
  } catch (error) {
    console.error('获取部门列表失败:', error)
    // 添加一些模拟数据，确保下拉框有内容显示
    departmentList.value = [
      { deptId: 1, deptName: '技术部' },
      { deptId: 2, deptName: '产品部' },
      { deptId: 3, deptName: '市场部' },
      { deptId: 4, deptName: '人力资源部' },
      { deptId: 5, deptName: '财务部' }
    ]
  }
}

// 组件挂载时获取流程配置列表和角色列表
onMounted(() => {
  if (viewMode.value === 'list') {
    loadProcessConfigs()
  }
  // 无论什么视图都加载角色列表和部门列表
  loadRoles()
  loadDepartments()
})

// 开始节点配置
const startFormId = ref('')
const startCondition = ref('')

// 结束节点配置
const endMessage = ref('')
const endAction = ref('none')

// 添加节点模态框相关
const showAddNodeModal = ref(false)
const newNodeForm = ref({
  nodeOrder: '',
  nodeName: '',
  department: '',
  role: ''
})
const errors = ref({})

// 添加新节点
const addNode = () => {
  // 重置表单和错误信息
  newNodeForm.value = {
    nodeOrder: '',
    nodeName: '',
    department: '',
    role: ''
  }
  errors.value = {}
  showAddNodeModal.value = true
}

// 关闭添加节点模态框
const closeAddNodeModal = () => {
  showAddNodeModal.value = false
}

// 提交添加节点表单
const submitAddNodeForm = async () => {
  // 验证表单
  let isValid = true
  errors.value = {}
  
  if (!newNodeForm.value.nodeOrder) {
    errors.value.nodeOrder = '请输入节点顺序'
    isValid = false
  }
  
  if (!newNodeForm.value.nodeName.trim()) {
    errors.value.nodeName = '请输入节点名'
    isValid = false
  }
  
  if (!newNodeForm.value.department.trim()) {
    errors.value.department = '请输入部门'
    isValid = false
  }
  
  if (!newNodeForm.value.role) {
    errors.value.role = '请选择角色'
    isValid = false
  }
  
  if (!currentProcessId.value) {
    errors.value.general = '请先创建或选择一个流程'
    isValid = false
  }
  
  // 只有表单验证通过才调用API创建节点
  if (isValid) {
    try {
      // 构建要发送的节点数据，符合用户要求的结构
      const nodeData = {
        processId: currentProcessId.value,
        nodeOrder: newNodeForm.value.nodeOrder,
        nodeName: newNodeForm.value.nodeName,
        department: newNodeForm.value.department,
        role: newNodeForm.value.role,
        nodeContent: {} // 空对象，如需要可根据实际需求填充
      }
      
      // 调用创建节点API
      const response = await createProcessNode(currentProcessId.value, nodeData)
      
      if (response && response.code === 200 && response.data) {
        // API调用成功，更新本地节点列表
        const createdNode = response.data
        // 为了保持一致性，添加必要的字段
        createdNode.nodeName = newNodeForm.value.nodeName
        createdNode.department = newNodeForm.value.department
        createdNode.role = newNodeForm.value.role
        createdNode.nodeOrder = newNodeForm.value.nodeOrder
        
        processNodes.value.push(createdNode)
        selectNode(createdNode)
        showAddNodeModal.value = false
        
        console.log('节点创建成功:', createdNode)
      } else {
        throw new Error(response?.message || '创建节点失败')
      }
    } catch (error) {
      console.error('创建节点失败:', error)
      errors.value.general = error.message || '创建节点失败，请重试'
    }
  }
}

// 删除节点
const deleteNode = (nodeId) => {
  if (confirm('确定要删除这个节点吗？')) {
    // 调用删除节点API
    if (currentProcessId.value) {
      deleteProcessNode(currentProcessId.value, nodeId)
        .then(() => {
          console.log('节点删除成功')
        })
        .catch(error => {
          console.error('节点删除失败', error)
          alert('节点删除失败，请重试')
        })
    }
    
    // 前端更新节点列表
    processNodes.value = processNodes.value.filter(node => node.id !== nodeId)
    if (selectedNode.value && selectedNode.value.id === nodeId) {
      selectedNode.value = null
    }
  }
}

// 选择节点
const selectNode = (node) => {
  // 确保开始和结束节点是带有id属性的对象
  if (node === 'start' || node === 'end') {
    selectedNode.value = { id: node }
  } else {
    selectedNode.value = node
  }
}

// 获取节点类型名称
const getNodeTypeName = (node) => {
  // 优先显示节点的role属性
  if (node.role) {
    return node.role
  }
  
  // 如果没有role属性，使用type属性获取节点类型名称
  const typeNames = {
    'approval': '审批节点',
    'task': '任务节点',
    'decision': '决策节点',
    'notification': '通知节点'
  }
  return typeNames[node.type] || 'role'
}

// 计算节点连接线
const processNodesWithConnections = computed(() => {
  // 简化处理，实际项目中可能需要更复杂的逻辑
  return processNodes.value
})

// 表单设计器相关状态
const showFormDesigner = ref(false)
const showPreview = ref(false)
const showJsonModal = ref(false)

// 当前编辑的任务ID
const currentTaskId = ref('')

// 组件分类展开状态
const expandedCategories = ref({
  basic: true,
  select: true,
  date: true,
  advanced: true
})

// 组件库定义
const basicComponents = ref([
  { id: 'input', name: '单行文本', type: 'input', icon: '📝' },
  { id: 'textarea', name: '多行文本', type: 'textarea', icon: '📋' },
  { id: 'divider', name: '分割线', type: 'divider', icon: '━' }
])

const selectComponents = ref([
  { id: 'select', name: '下拉选择', type: 'select', icon: '▼', options: [{ label: '选项1', value: '1' }, { label: '选项2', value: '2' }] },
  { id: 'checkbox', name: '多选框组', type: 'checkbox', icon: '☑️', options: [{ label: '选项1', value: '1' }, { label: '选项2', value: '2' }] },
  { id: 'radio', name: '单选框组', type: 'radio', icon: '🔘', options: [{ label: '选项1', value: '1' }, { label: '选项2', value: '2' }] }
])

const dateComponents = ref([
  { id: 'date', name: '日期选择', type: 'date', icon: '📅', dateValue: '' },
  { id: 'datetime', name: '日期时间', type: 'datetime', icon: '⏰', dateTimeValue: '' }
])

const advancedComponents = ref([
  { id: 'array', name: '数据容器', type: 'array', icon: '📦', items: [] }
])

// 表单组件列表
const formComponents = ref([])

// 当前选中的组件
const selectedComponentId = ref(null)
const selectedComponent = computed(() => {
  return formComponents.value.find(component => component.id === selectedComponentId.value)
})

// 正在编辑的子组件索引
const editingChildIndex = ref(null)

// 拖拽相关
const draggedComponent = ref(null)

// 格式化的JSON - 始终显示当前编辑的表单组件数据
const formattedJson = computed(() => {
  try {
    // 直接使用当前表单组件数据，确保显示最新的表单设计
    return JSON.stringify(formComponents.value, null, 2);
  } catch (error) {
    console.error('生成格式化JSON失败:', error);
    // 出错时提供友好的错误信息
    return `// JSON格式化失败: ${error.message}\n${JSON.stringify(formComponents.value || [], null, 2)}`;
  }
})

// 格式化节点内容为易读的JSON字符串
const formatNodeContent = (content) => {
  try {
    if (!content) return '';
    
    if (typeof content === 'string') {
      // 如果已经是字符串，尝试解析为JSON并重新格式化
      try {
        const parsedContent = JSON.parse(content);
        return JSON.stringify(parsedContent, null, 2);
      } catch (parseError) {
        // 如果解析失败，返回原始字符串
        return content;
      }
    } else if (typeof content === 'object') {
      // 如果是对象，直接字符串化
      return JSON.stringify(content, null, 2);
    } else {
      // 其他类型，转换为字符串
      return String(content);
    }
  } catch (error) {
    console.error('格式化节点内容失败:', error);
    return String(content || '');
  }
}

// 打开表单设计器
const openFormDesigner = (taskId) => {
  currentTaskId.value = taskId
  showFormDesigner.value = true
  
  // 根据任务ID找到对应的节点，并加载已保存的表单配置
  const node = processNodes.value.find(n => n.id === taskId)
  if (node && node.nodeContent) {
    try {
      // 加载已保存的表单配置到formComponents
      let formContent = [];
      
      if (typeof node.nodeContent === 'string') {
        try {
          // 尝试解析字符串为JSON对象
          formContent = JSON.parse(node.nodeContent);
        } catch (parseError) {
          console.warn('nodeContent是字符串但不是有效的JSON，可能是旧格式数据');
          formContent = []; // 解析失败时使用空数组
        }
      } else if (typeof node.nodeContent === 'object') {
        // 如果已经是对象，直接使用
        formContent = node.nodeContent;
      }
      
      // 确保是数组格式
      if (Array.isArray(formContent)) {
        formComponents.value = formContent.map(comp => ({ ...comp }))
        console.log('加载已保存的表单配置:', formComponents.value)
      } else {
        console.warn('表单内容不是数组格式，使用空数组');
        formComponents.value = [];
      }
    } catch (error) {
      console.error('加载表单配置失败:', error)
      // 加载失败时清空表单组件列表
      formComponents.value = []
      // 提供错误提示
      alert('加载表单配置时出错：' + error.message);
    }
  } else {
    // 没有已保存的表单配置，清空表单组件列表
    formComponents.value = []
  }
}

// 关闭表单设计器
const closeFormDesigner = () => {
  showFormDesigner.value = false
}

// 切换组件分类展开状态
const toggleCategory = (category) => {
  expandedCategories.value[category] = !expandedCategories.value[category]
}

// 选择组件
const selectComponent = (id) => {
  selectedComponentId.value = id
}

// 拖拽开始
const onDragStart = (component) => {
  draggedComponent.value = { ...component }
}

// 拖拽悬停
const onDragOver = (e) => {
  e.preventDefault()
}

// 拖拽放置
const onDrop = (e) => {
  e.preventDefault()
  if (draggedComponent.value) {
    // 创建新组件（添加唯一ID）
    const newComponent = {
      ...draggedComponent.value,
      id: `${draggedComponent.value.id}_${Date.now()}`,
      label: draggedComponent.value.name,
      required: false,
      width: '100%'
    }
    
    // 为日期和日期时间组件添加默认配置
    if (newComponent.type === 'date') {
      newComponent.dateValue = ''
    } else if (newComponent.type === 'datetime') {
      newComponent.dateTimeValue = ''
    }
    
    // 对于有选项的组件，深拷贝选项
    if (newComponent.options) {
      newComponent.options = JSON.parse(JSON.stringify(newComponent.options))
    }
    
    // 添加到表单组件列表
    formComponents.value.push(newComponent)
    
    // 选择新添加的组件
    selectComponent(newComponent.id)
  }
}

// 删除组件
const deleteComponent = (index) => {
  formComponents.value.splice(index, 1)
  selectedComponentId.value = null
}

// 复制组件
const copyComponent = (index) => {
  const componentToCopy = formComponents.value[index]
  const copiedComponent = JSON.parse(JSON.stringify(componentToCopy))
  copiedComponent.id = `${copiedComponent.id}_copy_${Date.now()}`
  formComponents.value.splice(index + 1, 0, copiedComponent)
}

// 添加选项
const addOption = () => {
  if (selectedComponent.value && selectedComponent.value.options) {
    selectedComponent.value.options.push({
      label: '新选项',
      value: Date.now().toString().slice(-4)
    })
  }
}

// 移除选项
const removeOption = (index) => {
  if (selectedComponent.value && selectedComponent.value.options) {
    selectedComponent.value.options.splice(index, 1)
  }
}

// 为子组件添加选项
const addChildOption = (childIndex) => {
  if (selectedComponent.value && selectedComponent.value.items && selectedComponent.value.items[childIndex].options) {
    selectedComponent.value.items[childIndex].options.push({
      label: '新选项',
      value: Date.now().toString().slice(-4)
    })
  }
}

// 移除子组件的选项
const removeChildOption = (childIndex, optionIndex) => {
  if (selectedComponent.value && selectedComponent.value.items && selectedComponent.value.items[childIndex].options) {
    selectedComponent.value.items[childIndex].options.splice(optionIndex, 1)
  }
}

// 添加数组子组件
const addArrayChild = () => {
  if (selectedComponent.value && selectedComponent.value.type === 'array') {
    // 创建一个默认的单行文本子组件
    const defaultChild = {
      id: `child_${Date.now()}`,
      type: 'input',
      name: `field_${Date.now().toString().slice(-4)}`,
      label: '子组件',
      placeholder: '请输入...',
      required: false,
      width: '100%'
    }
    
    // 初始化items数组（如果不存在）
    if (!selectedComponent.value.items) {
      selectedComponent.value.items = []
    }
    
    // 添加子组件
    selectedComponent.value.items.push(defaultChild)
  }
}

// 数据容器拖拽悬停
const onArrayDragOver = (e, arrayId) => {
  e.preventDefault()
  const arrayContainer = e.currentTarget
  arrayContainer.classList.add('drag-over')
}

// 编辑数组子组件
const editArrayChild = (index) => {
  editingChildIndex.value = index
}

// 数据容器拖拽放置
const onArrayDrop = (e, arrayId) => {
  e.preventDefault()
  e.stopPropagation() // 阻止事件冒泡，防止触发设计区域的onDrop
  
  // 移除拖拽样式
  const arrayContainer = e.currentTarget
  arrayContainer.classList.remove('drag-over')
  
  if (draggedComponent.value && draggedComponent.value.type !== 'array') {
    // 找到数据容器组件
    const arrayComponent = formComponents.value.find(component => component.id === arrayId)
    
    if (arrayComponent) {
      // 初始化items数组（如果不存在）
      if (!arrayComponent.items) {
        arrayComponent.items = []
      }
      
      // 创建子组件
      const childComponent = {
        ...draggedComponent.value,
        id: `${draggedComponent.value.id}_child_${Date.now()}`,
        label: draggedComponent.value.name,
        required: false,
        width: '100%'
      }
      
      // 为日期和日期时间组件添加默认配置
      if (childComponent.type === 'date') {
        childComponent.dateValue = ''
      } else if (childComponent.type === 'datetime') {
        childComponent.dateTimeValue = ''
      }
      
      // 对于有选项的组件，深拷贝选项
      if (childComponent.options) {
        childComponent.options = JSON.parse(JSON.stringify(childComponent.options))
      }
      
      // 添加到数据容器的items中
      arrayComponent.items.push(childComponent)
      
      // 选择数据容器组件
      selectComponent(arrayId)
    }
  }
}

// 删除数组子组件
const removeArrayChild = (index) => {
  if (selectedComponent.value && selectedComponent.value.items) {
    selectedComponent.value.items.splice(index, 1)
  }
}

// 上移组件
const moveComponentUp = (index) => {
  if (index > 0) {
    // 交换位置
    const temp = formComponents.value[index]
    formComponents.value[index] = formComponents.value[index - 1]
    formComponents.value[index - 1] = temp
    // 重新选择移动后的组件
    selectComponent(temp.id)
  }
}

// 下移组件
const moveComponentDown = (index) => {
  if (index < formComponents.value.length - 1) {
    // 交换位置
    const temp = formComponents.value[index]
    formComponents.value[index] = formComponents.value[index + 1]
    formComponents.value[index + 1] = temp
    // 重新选择移动后的组件
    selectComponent(temp.id)
  }
}

// 预览表单
const previewForm = () => {
  showPreview.value = true
}

// 关闭预览
const closePreview = () => {
  showPreview.value = false
}

// 处理预览表单提交
const handlePreviewSubmit = () => {
  // 创建一个对象来存储表单数据
  const formData = {}
  
  // 遍历所有组件，获取值
  formComponents.value.forEach(component => {
    // 在实际应用中，这里应该根据组件类型获取不同的值
    // 由于我们无法直接访问DOM元素，这里模拟获取值
    if (component.type === 'input' || component.type === 'textarea') {
      formData[component.name] = '示例值'; // 实际应用中应获取真实输入值
    } else if (component.type === 'date') {
      // 模拟日期选择，使用当前日期
      const today = new Date();
      const formattedDate = today.toISOString().split('T')[0]; // YYYY-MM-DD格式
      formData[component.name] = formattedDate;
    } else if (component.type === 'datetime') {
      // 模拟日期时间选择，使用当前日期时间
      const now = new Date();
      // 格式化日期时间为YYYY-MM-DDTHH:MM格式
      const year = now.getFullYear();
      const month = String(now.getMonth() + 1).padStart(2, '0');
      const day = String(now.getDate()).padStart(2, '0');
      const hours = String(now.getHours()).padStart(2, '0');
      const minutes = String(now.getMinutes()).padStart(2, '0');
      const formattedDateTime = `${year}-${month}-${day}T${hours}:${minutes}`;
      formData[component.name] = formattedDateTime;
    } else if (component.type === 'select') {
      formData[component.name] = component.options[0]?.value || ''; // 默认选择第一个选项
    } else if (component.type === 'radio') {
      formData[component.name] = component.options[0]?.value || ''; // 默认选择第一个选项
    } else if (component.type === 'checkbox') {
      // 对于复选框，存储选中的选项值数组
      formData[component.name] = component.options.slice(0, 2).map(option => option.value); // 默认选中前两个选项
    } else if (component.type === 'array' && component.items) {
      formData[component.name] = component.items.map(item => ({
        [item.name]: '示例子组件值'
      }));
    }
  });
  
  // 显示提交的数据
  console.log('表单提交数据:', formData);
  alert('表单提交成功！\n\n提交数据:\n' + JSON.stringify(formData, null, 2));
}

// 显示JSON
const showJson = () => {
  showJsonModal.value = true
}

// 关闭JSON
const closeJsonModal = () => {
  showJsonModal.value = false
}

// 复制JSON
const copyJson = () => {
  navigator.clipboard.writeText(formattedJson.value).then(() => {
    alert('JSON已复制到剪贴板');
  }).catch(err => {
    console.error('无法复制JSON:', err);
  });
}

// 保存表单
const saveForm = () => {
  // 获取表单JSON数据
  const formJson = JSON.stringify(formComponents.value, null, 2);
  const node = processNodes.value.find(n => n.id === currentTaskId.value);
  
  if (node && currentProcessId.value) {
    // 准备更新节点的数据
    const updateData = {
      nodeOrder: node.nodeOrder,
      nodeName: node.nodeName,
      department: node.department,
      role: node.role,
      nodeContent: formComponents.value // 直接使用对象格式
    };
    
    // 调用API更新节点数据
    updateProcessNode(currentProcessId.value, currentTaskId.value, updateData)
      .then(response => {
        console.log('节点更新成功:', response);
        
        // 更新本地节点数据，保持数据一致性
        node.nodeContent = formComponents.value;
        
        // 通知用户保存成功
        alert('表单已成功保存');
        
        // 关闭表单设计器
        closeFormDesigner();
      })
      .catch(error => {
        console.error('节点更新失败:', error);
        alert('保存失败：' + (error.message || '网络错误，请重试'));
      });
  } else {
    console.error('未找到对应的节点或流程ID');
    alert('保存失败：未找到对应的节点或流程ID');
  }
}

// 复制表单JSON到剪贴板
const copyJsonToClipboard = () => {
  navigator.clipboard.writeText(formattedJson.value).then(() => {
    alert('JSON已复制到剪贴板');
  }).catch(err => {
    console.error('无法复制JSON:', err);
  });
}

// 更新节点信息
const updateNodeInfo = () => {
  if (selectedNode.value && currentProcessId.value && selectedNode.value.id !== 'start' && selectedNode.value.id !== 'end') {
    // 准备更新节点的数据
    const updateData = {
      nodeOrder: selectedNode.value.nodeOrder,
      nodeName: selectedNode.value.nodeName || '',
      department: selectedNode.value.department || '',
      role: selectedNode.value.role || '',
      nodeContent: selectedNode.value.nodeContent || {}
    };
    
    // 调用API更新节点数据
    updateProcessNode(currentProcessId.value, selectedNode.value.id, updateData)
      .then(response => {
        console.log('节点更新成功:', response);
      })
      .catch(error => {
        console.error('节点更新失败:', error);
        // 注意：这里不弹出alert，避免频繁提示
      });
  }
}
</script>

<style scoped>
@import '../styles/custom-button.css';

.task-process-designer {
  padding: 20px;
  background-color: #f5f7fa;
  min-height: 100vh;
}

.page-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eaeaea;
  margin: 0 auto 15px;
  width: 95%;
  max-width: 1400px;
}

.page-header h2 {
  margin: 0;
  color: #333;
  font-size: 24px;
}

.task-process-designer {
  height: 100%;
  width: 100%;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  padding: 0;
  margin: 0;
}

.designer-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
  height: 10%; /* 降低为现在的一半，占页面上部10% */
  overflow: auto;
  min-height: 0;
}

.info-section {
  margin-bottom: 0;
}

/* 下方布局 - 左侧流程节点栏和右侧节点配置 */
.designer-bottom-layout {
  display: flex;
  gap: 20px;
  height: calc(100vh - 280px); /* 设置最大高度，确保在页面中完整展示 */
  flex: 1;
  min-height: 0;
  margin: 0 auto;
  width: 95%;
  max-width: 1400px;
}

/* 左侧流程节点栏 */
.nodes-section {
  flex: 0 0 40%; /* 占下部区域的40% */
  overflow-y: auto;
  height: 100%;
  max-height: 90%;
  min-height: 0;
  border-radius: var(--border-radius-lg);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  background-color: var(--bg-white);
  border: 1px solid var(--border-light);
}

/* 右侧节点配置 */
.configuration-section {
  flex: 1; /* 占下部区域的60% */
  overflow-y: auto;
  height: 100%;
  max-height: 90%;
  min-height: 0;
  border-radius: var(--border-radius-lg);
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  background-color: var(--bg-white);
  border: 1px solid var(--border-light);
}

/* 设计师底部布局中的卡片样式 */
.designer-bottom-layout .card {
  border: none !important;
  box-shadow: none !important;
  height: 100%;
}

/* 响应式调整 */
@media (max-width: 1200px) {
  .nodes-section {
    flex: 0 0 45%; /* 稍调整比例以适应中等屏幕 */
  }
}

@media (max-width: 768px) {
  .task-process-designer {
    height: auto;
    min-height: 100vh;
  }
  
  .designer-container {
    height: auto;
    min-height: 200px; /* 响应式设计中也适当降低最小高度 */
  }
  
  .designer-bottom-layout {
    flex-direction: column;
    height: auto;
    min-height: 60vh;
  }
  
  .nodes-section,
  .configuration-section {
    flex: 1;
    min-height: 300px;
  }
}

.designer-section {
  background: white;
  border-radius: 8px;
  padding: 20px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  height: 100%;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

.designer-section h3 {
  margin: 0 0 20px 0;
  color: #333;
  font-size: 18px;
  border-bottom: 2px solid #eaeaea;
  padding-bottom: 10px;
}

.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 20px;
}

.section-header h3 {
  border-bottom: none;
  margin-bottom: 0;
}

/* 表单样式 */
.form-container {
  display: flex;
  flex-direction: column;
  gap: 15px;
}

.form-row {
  display: flex;
  gap: 20px;
}

.form-item {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.form-label {
  font-weight: 500;
  color: #555;
  font-size: 14px;
}

.input, .select, .textarea {
  padding: 10px 12px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  font-size: 14px;
  transition: border-color 0.3s;
}

.input:focus, .select:focus, .textarea:focus {
  outline: none;
  border-color: #409eff;
}

.textarea {
  resize: vertical;
  min-height: 80px;
}

/* 节点样式 */
.nodes-container {
  position: relative;
  padding: 20px 0;
  min-height: 200px;
  flex: 1;
  overflow-y: auto;
}

.node-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 15px 20px;
  margin-bottom: 10px;
  background: #f8f9fa;
  border: 2px solid transparent;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s;
  position: relative;
}

.node-item:hover {
  background: #e9ecef;
}

.node-item.selected {
  border-color: #409eff;
  background: #e3f2fd;
}

.start-node {
  background: #e8f5e9 !important;
  border-color: #4caf50;
}

.start-node.selected {
  background: #c8e6c9 !important;
}

.end-node {
  background: #ffebee !important;
  border-color: #f44336;
}

.end-node.selected {
  background: #ffcdd2 !important;
}

.node-icon {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: white;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.node-icon svg {
  color: #409eff;
}

.start-node .node-icon svg {
  color: #4caf50;
}

.end-node .node-icon svg {
  color: #f44336;
}

.node-content {
  flex: 1;
}

.node-title {
  font-weight: 500;
  color: #333;
  margin-bottom: 4px;
}

.node-type {
  font-size: 12px;
  color: #666;
}

.node-delete-btn {
  width: 32px;
  height: 32px;
  border: none;
  background: #ff4d4f;
  color: white;
  border-radius: 4px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: background-color 0.3s;
}

.node-delete-btn:hover {
  background: #ff7875;
}

/* 连接线 */
.connections {
  position: absolute;
  top: 0;
  left: 20px;
  right: 20px;
  bottom: 0;
  pointer-events: none;
}

.connection-line {
  position: absolute;
  width: 2px;
  background: #ccc;
  left: 20px;
}

/* 节点配置 */
.no-selection {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  background: #f8f9fa;
  border-radius: 8px;
  color: #999;
}

.node-configuration {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.config-section {
  padding: 20px;
  background: #f8f9fa;
  border-radius: 8px;
}

.config-section h4 {
  margin: 0 0 15px 0;
  color: #333;
  font-size: 16px;
}

.form-association {
  display: flex;
  gap: 10px;
}

.form-association .input {
  flex: 1;
  background: #e9ecef;
}

/* 模态框样式 */
.modal {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.modal-content {
  background: white;
  border-radius: 8px;
  width: 90%;
  max-width: 500px;
  max-height: 90vh;
  overflow-y: auto;
  box-shadow: var(--shadow-lg);
}

.modal-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 20px;
  border-bottom: 1px solid var(--border-base);
}

.modal-header h3 {
  margin: 0;
  color: var(--text-primary);
}

.modal-close {
  background: none;
  border: none;
  font-size: 24px;
  cursor: pointer;
  color: var(--text-secondary);
  padding: 0;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 4px;
  transition: background-color 0.3s;
}

.modal-close:hover {
  background-color: var(--bg-light);
}

.modal-body {
  padding: 20px;
}

.modal-footer {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  padding: 20px;
  border-top: 1px solid var(--border-base);
}

/* 表单验证错误信息 */
.error-message {
  color: var(--danger-color);
  font-size: 12px;
  margin-top: 4px;
}

.required {
  color: var(--danger-color);
}


/* 表单设计器样式 - 美化版 */
  :root {
    --designer-primary: #1890ff;
    --designer-primary-light: #e6f7ff;
    --designer-secondary: #595959;
    --designer-light: #f0f2f5;
    --designer-border: #d9d9d9;
    --designer-success: #52c41a;
    --designer-warning: #faad14;
    --designer-danger: #ff4d4f;
    --designer-text-primary: #1f2329;
    --designer-text-secondary: #595959;
    --designer-text-tertiary: #8c8c8c;
    --designer-bg-light: #f5f5f5;
  }

  .designer-modal {
    width: 90%;
    height: 90vh;
    max-width: 1600px;
    max-height: 90vh;
    display: flex;
    flex-direction: column;
  }
  
  .json-modal {
    width: 80%;
    max-width: 1200px;
  }
  
  .designer-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 1px solid #eee;
  }
  
  .title-container {
    flex: 1;
  }
  
  .page-title {
    margin: 0;
    font-size: 20px;
    color: #333;
  }
  
  .breadcrumb {
    font-size: 12px;
    color: #999;
    margin-top: 4px;
  }
  
  .action-buttons {
    display: flex;
    gap: 10px;
  }
  
  .designer-content {
    display: flex;
    flex: 1;
    overflow: hidden;
  }
  
  /* 左侧组件库 */
  .components-panel {
    width: 220px;
    background: var(--designer-bg-light);
    padding: 15px;
    overflow-y: auto;
    flex-shrink: 0;
    border-right: 1px solid var(--designer-border);
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
  }
  
  .panel-title {
    margin: 0 0 15px 0;
    font-size: 14px;
    font-weight: 600;
    color: var(--designer-text-primary);
    padding-bottom: 8px;
    border-bottom: 2px solid var(--designer-primary);
    display: inline-block;
  }
  
  .component-category {
    margin-bottom: 12px;
    border-radius: 6px;
    overflow: hidden;
    background: white;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  }
  
  .category-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    background: var(--designer-primary-light);
    border-radius: 4px;
    cursor: pointer;
    font-size: 13px;
    font-weight: 500;
    color: var(--designer-primary);
    transition: background-color 0.3s;
  }
  
  .category-header:hover {
    background: #bae7ff;
  }
  
  .category-name {
    flex: 1;
  }
  
  .icon.rotate {
    transform: rotate(180deg);
    transition: transform 0.3s ease;
  }
  
  .category-content {
    padding: 6px;
  }
  
  .component-item {
    display: flex;
    align-items: center;
    padding: 8px 12px;
    margin-bottom: 6px;
    background: white;
    border-radius: 4px;
    cursor: grab;
    font-size: 13px;
    color: var(--designer-text-secondary);
    transition: all 0.2s;
    border: 1px solid transparent;
  }
  
  .component-item:hover {
    background: var(--designer-primary-light);
    border-color: var(--designer-primary);
    color: var(--designer-primary);
    transform: translateX(2px);
  }
  
  .component-item:active {
    cursor: grabbing;
  }
  
  .component-icon {
    margin-right: 8px;
    font-size: 16px;
  }
  
  /* 中间设计区域 */
  .design-area {
    flex: 1;
    padding: 20px;
    overflow-y: auto;
    background: #f7f8fa;
    border-left: 1px solid var(--designer-border);
    border-right: 1px solid var(--designer-border);
  }
  
  .form-container {
    max-width: 800px;
    margin: 0 auto;
    min-height: 100%;
    background: white;
    padding: 20px;
    border-radius: 8px;
    box-shadow: 0 0 15px rgba(0, 0, 0, 0.03);
  }
  
  .form-component {
    margin-bottom: 16px;
    padding: 15px;
    background: white;
    border: 1px solid var(--designer-border);
    border-radius: 6px;
    position: relative;
    transition: all 0.3s;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
  }
  
  .form-component.selected {
    border-color: var(--designer-primary);
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
    background: var(--designer-primary-light);
    transform: translateY(-2px);
    box-shadow: 0 4px 12px rgba(24, 144, 255, 0.15);
  }
  
  .component-content {
    margin-bottom: 8px;
  }
  
  .component-label {
    font-weight: 500;
    margin-bottom: 8px;
    font-size: 14px;
    color: var(--designer-text-primary);
    display: flex;
    align-items: center;
  }
  
  .component-label.required::after {
    content: '*';
    color: var(--designer-danger);
    margin-left: 4px;
  }
  
  .component-preview {
    display: flex;
    align-items: center;
  }
  
  .empty-form {
    text-align: center;
    padding: 60px 20px;
    color: #999;
    background: #fafafa;
    border-radius: 8px;
  }
  
  .empty-icon {
    font-size: 48px;
    margin-bottom: 16px;
  }
  
  .empty-text {
    font-size: 16px;
  }
  
  /* 右侧属性配置面板 */
  .properties-panel {
    width: 320px;
    background: var(--designer-bg-light);
    padding: 15px;
    overflow-y: auto;
    flex-shrink: 0;
    border-left: 1px solid var(--designer-border);
    box-shadow: 0 0 10px rgba(0, 0, 0, 0.05);
  }
  
  .property-section {
    margin-bottom: 20px;
    background: white;
    padding: 12px;
    border-radius: 6px;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  }
  
  .section-title {
    margin: 0 0 10px 0;
    font-size: 13px;
    font-weight: 600;
    color: var(--designer-text-primary);
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding-bottom: 6px;
    border-bottom: 1px solid var(--designer-border);
  }
  
  .property-item {
    margin-bottom: 12px;
  }
  
  .property-label {
    display: block;
    margin-bottom: 4px;
    font-size: 12px;
    color: var(--designer-text-secondary);
    font-weight: 500;
  }
  
  .property-input {
    width: 100%;
    padding: 6px 12px;
    border: 1px solid var(--designer-border);
    border-radius: 4px;
    font-size: 13px;
    transition: all 0.3s;
  }
  
  .property-input:focus {
    outline: none;
    border-color: var(--designer-primary);
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  }
  
  .property-input.small-input {
    font-size: 12px;
    padding: 4px 6px;
  }
  
  .checkbox-item {
    display: flex;
    align-items: center;
  }
  
  .checkbox-label {
    display: flex;
    align-items: center;
    font-size: 13px;
    cursor: pointer;
  }
  
  .checkbox-label input[type="checkbox"] {
    margin-right: 6px;
  }
  
  .no-selection {
    text-align: center;
    padding: 40px 20px;
    color: #999;
  }
  
  /* 组件操作按钮 */
  .component-actions {
    position: absolute;
    top: 10px;
    right: 10px;
    display: flex;
    gap: 4px;
    opacity: 0;
    transition: opacity 0.2s, transform 0.2s;
    transform: translateY(-5px);
  }
  
  .form-component:hover .component-actions {
    opacity: 1;
    transform: translateY(0);
  }
  
  .action-btn {
    width: 26px;
    height: 26px;
    border: none;
    background: white;
    border-radius: 4px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--designer-text-secondary);
    border: 1px solid var(--designer-border);
    transition: all 0.3s;
  }
  
  .action-btn:hover {
    color: var(--designer-primary);
    border-color: var(--designer-primary);
    background: var(--designer-primary-light);
    transform: translateY(-1px);
  }
  
  .action-btn:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }
  
  /* 选项配置 */
  .option-item {
    display: flex;
    gap: 8px;
    margin-bottom: 8px;
    align-items: center;
    padding: 6px;
    background: white;
    border-radius: 4px;
    border: 1px solid var(--designer-border);
  }
  
  .option-input {
    flex: 1;
    padding: 6px 10px;
    border: 1px solid var(--designer-border);
    border-radius: 4px;
    font-size: 12px;
    transition: all 0.3s;
  }
  
  .option-input:focus {
    outline: none;
    border-color: var(--designer-primary);
  }
  
  .remove-option-btn {
    width: 24px;
    height: 24px;
    border: none;
    background: var(--designer-danger);
    color: white;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s;
  }
  
  .remove-option-btn:hover {
    background: #ff7875;
    transform: scale(1.05);
  }
  
  .add-option-btn {
    width: 100%;
    padding: 6px;
    border: 1px dashed var(--designer-border);
    background: white;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    color: var(--designer-text-secondary);
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s;
  }
  
  .add-option-btn:hover {
    border-color: var(--designer-primary);
    color: var(--designer-primary);
    background: var(--designer-primary-light);
  }
  
  .add-option-btn::before {
    content: '+';
    margin-right: 4px;
    font-weight: bold;
  }
  
  .add-option-btn.small-btn {
    padding: 4px 8px;
    font-size: 11px;
  }
  
  /* 数组组件样式 */
  .array-container {
    width: 100%;
    padding: 15px;
    border: 1px dashed var(--designer-border);
    border-radius: 6px;
    background: white;
    transition: all 0.3s;
  }
  
  .array-container.drag-over {
    border-color: var(--designer-primary);
    background: var(--designer-primary-light);
    box-shadow: 0 0 10px rgba(24, 144, 255, 0.1);
  }
  
  .array-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 12px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--designer-border);
  }
  
  .array-count {
    font-size: 12px;
    color: var(--designer-text-tertiary);
    font-style: italic;
  }
  
  .array-items {
    margin-top: 8px;
  }
  
  .array-item {
    padding: 12px;
    background: white;
    border: 1px solid var(--designer-border);
    border-radius: 6px;
    margin-bottom: 10px;
    transition: all 0.3s;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  }
  
  .array-item:hover {
    border-color: var(--designer-primary);
    box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
  }
  
  .array-child-item {
    margin-bottom: 8px;
    padding: 10px;
    background: white;
    border: 1px solid var(--designer-border);
    border-radius: 4px;
    transition: all 0.3s;
  }
  
  .array-child-header {
    display: flex;
    align-items: center;
    margin-bottom: 8px;
    padding-bottom: 6px;
    border-bottom: 1px dashed var(--designer-border);
  }
  
  .edit-child-btn {
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px 8px;
    margin-right: 8px;
    color: var(--designer-primary);
    border-radius: 4px;
    transition: all 0.3s;
  }
  
  .edit-child-btn:hover {
    background: var(--designer-primary-light);
  }
  
  .remove-child-btn {
    background: var(--designer-danger);
    color: white;
    border: none;
    width: 24px;
    height: 24px;
    border-radius: 4px;
    cursor: pointer;
    margin-left: auto;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s;
  }
  
  .remove-child-btn:hover {
    background: #ff7875;
    transform: scale(1.05);
  }
  
  .array-child-properties {
    padding: 8px;
    background: #fafafa;
    border-radius: 4px;
  }
  
  .empty-array {
    text-align: center;
    padding: 20px;
    color: #999;
    font-size: 12px;
  }
  
  .add-child-btn {
    width: 100%;
    padding: 6px;
    border: 1px dashed #ddd;
    background: white;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    color: #666;
  }
  
  .save-child-btn {
    margin-top: 8px;
    padding: 4px 12px;
    background: #1890ff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
  }
  
  /* 预览样式 */
  .preview-input,
  .preview-select,
  .preview-date,
  .preview-datetime {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--designer-border);
    border-radius: 4px;
    font-size: 13px;
    transition: all 0.3s;
  }
  
  .preview-input:focus,
  .preview-select:focus,
  .preview-date:focus,
  .preview-datetime:focus {
    outline: none;
    border-color: var(--designer-primary);
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  }
  
  .preview-textarea {
    width: 100%;
    padding: 8px 12px;
    border: 1px solid var(--designer-border);
    border-radius: 4px;
    font-size: 13px;
    min-height: 80px;
    resize: vertical;
    transition: all 0.3s;
  }
  
  .preview-textarea:focus {
    outline: none;
    border-color: var(--designer-primary);
    box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
  }
  
  .checkbox-group,
  .radio-group {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin-top: 8px;
  }
  
  .checkbox-group label,
  .radio-group label {
    display: flex;
    align-items: center;
    cursor: pointer;
    font-size: 13px;
    color: var(--designer-text-secondary);
    padding: 4px 8px;
    border-radius: 4px;
    transition: all 0.3s;
  }
  
  .checkbox-group label:hover,
  .radio-group label:hover {
    background: var(--designer-primary-light);
    color: var(--designer-primary);
  }
  
  .checkbox-group input,
  .radio-group input {
    margin-right: 6px;
  }
  
  .divider {
    height: 1px;
    background: var(--designer-border);
    width: 100%;
    margin: 20px 0;
    position: relative;
  }
  
  .divider-label {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    padding: 0 12px;
    font-size: 12px;
    color: var(--designer-text-tertiary);
    font-weight: 500;
  }
  
  .preview-form {
    max-width: 600px;
    margin: 0 auto;
  }
  
  .preview-form-component {
    margin-bottom: 20px;
  }
  
  /* JSON预览样式 */
  .json-preview {
    background: #f8f9fa;
    padding: 16px;
    border-radius: 6px;
    overflow-x: auto;
    font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
    font-size: 13px;
    line-height: 1.5;
    max-height: 500px;
    overflow-y: auto;
    border: 1px solid var(--designer-border);
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
  }
  
  .json-key {
    color: #0451a5;
  }
  
  .json-string {
    color: #a31515;
  }
  
  .json-number {
    color: #098658;
  }
  
  .json-boolean {
    color: #0000ff;
  }
  
  .json-null {
    color: #777777;
  }
  
  /* 工具提示样式 */
  .tooltip {
    position: relative;
  }
  
  .tooltip .tooltiptext {
    visibility: hidden;
    width: 120px;
    background-color: #555;
    color: #fff;
    text-align: center;
    border-radius: 6px;
    padding: 5px;
    position: absolute;
    z-index: 1;
    bottom: 125%;
    left: 50%;
    margin-left: -60px;
    opacity: 0;
    transition: opacity 0.3s;
    font-size: 12px;
  }
  
  .tooltip:hover .tooltiptext {
    visibility: visible;
    opacity: 1;
  }
  
  /* 流程基本信息卡片样式 */
  .process-info-card {
    margin: 0 auto var(--spacing-sm) auto;
    margin-bottom: var(--spacing-sm);
    border-radius: var(--border-radius-lg);
    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
    background-color: var(--bg-white);
    border: 1px solid var(--border-light);
    width: 95%;
    max-width: 1400px;
    padding: 8px 20px; /* 进一步减小内边距，大幅降低高度 */
    transition: all 0.3s ease;
    height: auto; /* 自动高度，根据内容调整 */
  }
  
  .process-info-card:hover {
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  }
  
  /* 表单行和表单项样式调整 - 确保流程名称和描述各占一半 */
  .process-info-card .form-row {
    display: flex;
    gap: 24px;
    width: 100%;
    justify-content: flex-start;
  }
  
  .process-info-card .section-title {
    margin: 0 0 8px 0; /* 减小标题下方间距 */
    font-size: 16px; /* 减小标题字体大小 */
    color: var(--text-primary);
    font-weight: 600;
    display: flex;
    align-items: center;
  }
  
  .process-info-card .section-title::before {
    content: '';
    display: inline-block;
    width: 4px;
    height: 20px;
    background-color: var(--primary-color);
    border-radius: 2px;
    margin-right: 10px;
  }
  
  /* 表单容器样式 - 确保没有额外边框 */
  .process-info-card .form-container {
    border: none !important;
    box-shadow: none !important;
    background: transparent !important;
  }
  
  .process-info-card .form-row {
    display: flex;
    gap: 24px;
    width: 100%;
    border: none !important;
  }
  
  .process-info-card .form-item {
    flex: 1; /* 每个表单项各占一半宽度 */
    display: flex;
    flex-direction: column;
    border: none !important;
    min-width: 0; /* 确保flex项目可以缩小 */
  }
  
  .process-info-card .form-label {
    margin-bottom: 10px;
    font-weight: 500;
    color: var(--text-regular);
    font-size: 14px;
    transition: color 0.3s;
  }
  
  .process-info-card .input.form-control,
  .process-info-card .select.form-control {
    padding: 8px 16px;
    border: 1px solid var(--border-base);
    border-radius: var(--border-radius-base);
    font-size: 14px;
    height: 40px;
    transition: all 0.3s ease;
    background-color: var(--bg-white);
    box-shadow: none !important;
  }
  
  .process-info-card .input.form-control:focus,
  .process-info-card .select.form-control:focus {
    outline: none;
    border-color: #409eff;
    box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2) !important;
  }
  
  .process-info-card .input.form-control::placeholder {
    color: var(--text-placeholder);
  }
  
  /* 节点配置区域样式 */
  .no-selection {
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 300px;
    background-color: var(--bg-soft);
    border-radius: var(--border-radius-md);
    border: 2px dashed var(--border-light);
  }
  
  .no-selection-content {
    text-align: center;
    color: var(--text-placeholder);
  }
  
  .no-selection-icon {
    opacity: 0.5;
    margin-bottom: 12px;
  }
  
  .node-configuration {
    padding: 20px;
  }
  
  .config-section {
    background-color: var(--bg-white);
    border-radius: var(--border-radius-md);
    padding: 20px;
    margin-bottom: 16px;
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
    border: 1px solid var(--border-light);
  }
  
  .config-section h4 {
    margin: 0 0 16px 0;
    font-size: 16px;
    color: var(--text-primary);
    font-weight: 600;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border-light);
  }
  
  .node-configuration .form-item {
    margin-bottom: 20px;
  }
  
  .node-configuration .form-item:last-child {
    margin-bottom: 0;
  }
  
  .node-configuration .form-label {
    margin-bottom: 8px;
    font-weight: 500;
    color: var(--text-regular);
    font-size: 14px;
  }
  
  .node-configuration .input.form-control,
  .node-configuration .select.form-control,
  .node-configuration .textarea.form-control {
    padding: 8px 12px;
    border: 1px solid var(--border-base);
    border-radius: var(--border-radius-base);
    font-size: 14px;
    transition: all 0.3s ease;
    width: 100%;
  }
  
  .node-configuration .textarea.form-control {
    min-height: 80px;
    resize: vertical;
  }
  
  .node-configuration .input.form-control:focus,
  .node-configuration .select.form-control:focus,
  .node-configuration .textarea.form-control:focus {
    outline: none;
    border-color: #409eff;
    box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.2);
  }
  
  .node-configuration .input.form-control:read-only {
    background-color: var(--bg-soft);
    color: var(--text-regular);
    cursor: not-allowed;
  }
  
  /* 初始界面样式 */
  .initial-view {
    padding: 20px;
  }
  
  .process-list-card {
    background: white;
    border-radius: 8px;
    padding: 20px;
    margin-top: 20px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }
  
  /* 加载状态样式 */
  .loading-state {
    text-align: center;
    padding: 60px 20px;
    color: #999;
  }
  
  .loading-icon {
    font-size: 48px;
    margin-bottom: 16px;
    animation: spin 1s linear infinite;
  }
  
  .loading-text {
    font-size: 18px;
    color: #666;
  }
  
  @keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
  }
  
  /* 流程列表样式 */
  .process-list {
    margin-top: 20px;
  }
  
  .process-item-header {
    display: flex;
    padding: 12px 16px;
    background-color: #f5f7fa;
    border-radius: 4px;
    font-weight: 600;
    color: #606266;
    font-size: 14px;
  }
  
  .process-item {
    display: flex;
    align-items: center;
    padding: 16px;
    border-bottom: 1px solid #f0f0f0;
    transition: background-color 0.2s;
  }
  
  .process-item:hover {
    background-color: #f5f7fa;
  }
  
  .process-name-column {
    flex: 0 0 30%;
    color: #303133;
  }
  
  .process-description-column {
    flex: 1;
    color: #606266;
  }
  
  .process-actions-column {
    flex: 0 0 160px;
    display: flex;
    gap: 8px;
    justify-content: flex-end;
  }
  
  .btn-sm {
    padding: 4px 12px;
    font-size: 12px;
  }
  
  .btn-danger {
    background-color: #f56c6c;
    border-color: #f56c6c;
  }
  
  .btn-danger:hover {
    background-color: #f78989;
    border-color: #f78989;
  }
  
  .empty-state {
    text-align: center;
    padding: 60px 20px;
    color: #999;
  }
  
  .empty-icon {
    font-size: 48px;
    margin-bottom: 16px;
  }
  
  .empty-text {
    font-size: 18px;
    margin-bottom: 8px;
    color: #666;
  }
  
  .empty-subtext {
    font-size: 14px;
  }
  
  /* 节点样式优化 */
  .node-item {
    transition: all 0.3s ease;
  }
  
  .node-item:hover {
    transform: translateX(4px);
  }
  
  .node-item.selected {
    background-color: #ecf5ff;
    border-color: #409eff;
  }
  
  /* 响应式设计 */
  @media (max-width: 1200px) {
    .components-panel {
      width: 180px;
    }
    
    .properties-panel {
      width: 250px;
    }
  }
  
  @media (max-width: 768px) {
    .designer-content {
      flex-direction: column;
    }
    
    .components-panel,
    .properties-panel {
      width: 100%;
      border: none;
      border-bottom: 1px solid #ddd;
      max-height: 200px;
    }
    
    .designer-modal {
      height: 95vh;
      width: 95%;
    }
    
    /* 流程基本信息响应式调整 */
    .form-container .form-row {
      flex-direction: column !important;
      gap: 0 !important;
    }
    
    .form-container .form-item {
      width: 100% !important;
      flex: none !important;
      margin-bottom: 16px;
    }
  }
  </style>